package com.arpa.ntocc.common.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.jpush.api.report.UsersResult;
import com.arpa.ntocc.common.common.cache.DictCache;
import com.arpa.ntocc.common.common.cache.DictCacheDO;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.dto.DictDTO;
import com.arpa.ntocc.common.domain.entity.Dict;
import com.arpa.ntocc.common.domain.vo.DictVO;
import com.arpa.ntocc.common.mapper.DictMapper;
import com.arpa.ntocc.common.service.IDictService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 数据字典表 服务实现类
 * </p>
 *
 * @author liuyj
 * @since 2019-11-25
 */
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements IDictService {

    private static final String SUCCESS = "success";
    @Autowired
    DictCache dictCache;
    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    public boolean save(Dict entity) {
        if(StringUtils.isBlank(entity.getCode())){
            entity.setCode(IdUtil.simpleUUID());
        }else{
            //如果code为自定义，查询该类型下code是否已存在
            if(existCode(entity)){
                return false;
            }
        }
        if(StringUtils.isBlank(entity.getCreatedBy())){
            entity.setCreatedBy(UserUtil.getCode());
        }
        entity.setBranchCode(UserUtil.getBranchCode());
        dictCache.flushCache(entity.getType(),entity.getCode(),UserUtil.getBranchCode());
        return super.save(entity);
    }
    private boolean existCode(Dict entity){
        //如果code为自定义，查询该类型、该所属机构下code是否已存在
       /* DictDTO query=new DictDTO();
        query.setCode(entity.getCode());
        query.setType(entity.getType());
        query.setBranchCode(UserUtil.getBranchCode());

        DictVO dictVOSum=baseMapper.queryListSum(query);*/
        int count = this.count(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, entity.getCode())
                .eq(Dict::getBranchCode, UserUtil.getBranchCode()).eq(Dict::getType, entity.getType()));
        return count>0;
    }

    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    public int updateByCode(DictDTO entity) {
        String groupCode = UserUtil.getBranchCode();
        Dict dict = new Dict();
        BeanUtils.copyProperties(entity,dict);
        if(StringUtils.isBlank(dict.getModifiedBy())){
            dict.setModifiedBy(UserUtil.getCode());
        }
        dictCache.flushCache(entity.getType(),entity.getCode(),groupCode);
        return baseMapper.update(dict,new QueryWrapper<Dict>().lambda().eq(Dict::getCode,entity.getOldCode()).eq(Dict::getBranchCode,groupCode));

    }

    /**
     * 查询列表
     * @param dictDTO
     * @return
     */
    @Override
    public List<DictVO> queryList(DictDTO dictDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StringUtils.isEmpty(dictDTO.getSortField())){
            dictDTO.setSortField("sort");
        }
            dictDTO.setSortField(CommonUtil.camel2Underline(dictDTO.getSortField()));
        List<DictVO> dictVOList = baseMapper.queryList(dictDTO);
        return dictVOList;
    }

    /**
     * 查询合计,包含总数
     * @param dictDTO
     * @return
     */
    @Override
    public DictVO queryListSum(DictDTO dictDTO){
        dictDTO.setBranchCode(UserUtil.getBranchCode());
        DictVO dictVO = baseMapper.queryListSum(dictDTO);
        return dictVO;
    }

    /**
     * 查询缓存列表
     * 结构：多个字典类型和子列表
     * @param types
     * @return
     */
    @Override
    public List<DictVO> queryCacheList(List<String> types) {
        List<DictVO> dictVOList=new ArrayList<>();
        for(String type:types){
            DictVO dictVO=new DictVO();
            dictVO.setType(type);
            //菜鸟的物流编码用淘宝的一样的
            if(type.equalsIgnoreCase("CAINIAO")){
                dictVO.setType("TB");
                type = "TB";
            }
            //查询字典类型`
            DictCacheDO dictDO = dictCache.get("dictType",type,UserUtil.getBranchCode());
            if(dictDO!=null){
                dictVO.setName(dictDO.getName());
                List<DictCacheDO> dictCacheDOList = dictCache.getListByType(type,UserUtil.getBranchCode());
                dictVO.setDictList(dictCacheDOList);
            } else {
                //数据字典为空时，设置集合为空，便于前端展示
                dictVO.setDictList(new ArrayList<DictCacheDO>());
            }
            dictVOList.add(dictVO);
        }
        return dictVOList;
    }

    /**
     * 删除数据字典并刷新缓存
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAndFlushCache(List<String> ids) {
        List<Dict> dictList=baseMapper.selectList(new QueryWrapper<Dict>().lambda().in(Dict::getId,ids).eq(Dict::getBranchCode,UserUtil.getBranchCode()));
        if(CollectionUtils.isEmpty(dictList)){
            throw new ServiceException("没有查询到要删除的记录");
        }
        for(Dict dict:dictList){
            dictCache.flushCache(dict.getType(),dict.getCode(),UserUtil.getBranchCode());
        }
        baseMapper.delete(new QueryWrapper<Dict>().lambda().in(Dict::getId,ids).eq(Dict::getBranchCode,UserUtil.getBranchCode()));
    }

    @Override
    public Map<String, Object> batchUpdateStatus(List<String> list,Integer status,String type) {
        Map<String, Object> result;
        result = new HashMap<>();
        int num = updateStatus(list, status, type);
        result.put(SUCCESS,num);
        return result;
    }

    private int updateStatus(List<String> codes,Integer status,String type){
        int num = 0;
        boolean flag = this.update(new UpdateWrapper<Dict>().lambda().set(Dict::getStatus, status).in(Dict::getCode, codes)
        .eq(Dict::getBranchCode,UserUtil.getBranchCode()));
        if (flag) {
            for (String code : codes) {
                dictCache.flushCache(type,code,UserUtil.getBranchCode());
                num ++;
            }
        }
        return num;
    }
}
